package com.lorizz.docrepo.model.impl;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Calendar;

import javax.jcr.Binary;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;

import com.lorizz.docrepo.DocrepoException;
import com.lorizz.docrepo.model.Document;
import com.lorizz.docrepo.repository.impl.JcrDocumentRepositoryConstants;
import com.lorizz.docrepo.repository.impl.JcrUtils;

public class DocumentImpl extends ItemImpl implements Document {

    private static final long serialVersionUID = 1L;

    public DocumentImpl(Node n) {
        this.node = n;
        try {
            session = n.getSession();
        } catch (RepositoryException e) {
            throw new DocrepoException(e);
        }
    }

    public DocumentImpl(FolderImpl parent, String name) {
        session = parent.getSession();
        Node n = parent.getNode();
        try {
            node = n.addNode(name, JcrDocumentRepositoryConstants.NT_DOCUMENT);
        } catch (RepositoryException e) {
            throw new DocrepoException(e);
        }
    }

    @Override
    public byte[] getData() {
        byte[] ret = null;
        try {
            Node n = node.getNode(Node.JCR_CONTENT);
            Binary bin = JcrUtils.nullSafeGetPropertyValue(n,
                    Property.JCR_DATA, PropertyType.BINARY);
            ret = JcrUtils.readBinary(bin);
        } catch (PathNotFoundException e) {
        } catch (RepositoryException e) {
            throw new DocrepoException(e);
        }
        return ret;
    }

    @Override
    public Calendar getLastModified() {
        return JcrUtils.nullSafeGetPropertyValue(node,
                Property.JCR_LAST_MODIFIED, PropertyType.DATE);
    }

    @Override
    public String getLastModifiedBy() {
        return JcrUtils.nullSafeGetPropertyValue(node,
                Property.JCR_LAST_MODIFIED_BY, PropertyType.STRING);
    }

    @Override
    public void setData(byte[] data) {
        setData(new ByteArrayInputStream(data));
    }

    @Override
    public void setData(InputStream is) {
        try {
            Node resource;
            if (node.hasNode(Node.JCR_CONTENT)) {
                resource = node.getNode(Node.JCR_CONTENT);
            } else {
                resource = node.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
            }
            resource.setProperty(Property.JCR_DATA, session.getValueFactory()
                    .createBinary(is));
        } catch (RepositoryException e) {
            throw new DocrepoException(e);
        }
    }

    @Override
    public void checkout() {
        try {
            session.getWorkspace().getVersionManager().checkout(node.getPath());
        } catch (RepositoryException e) {
            throw new DocrepoException(e);
        }
    }

    @Override
    public void checkin() {
        try {
            session.getWorkspace().getVersionManager().checkin(node.getPath());
        } catch (RepositoryException e) {
            throw new DocrepoException(e);
        }
    }

}
